using System;
using System.Collections.Generic;
using System.Text;
using Forecast.Database;

namespace Forecast.Business
{
    public class RemoveOffer
    {
        #region Variables

        private Offer _offer;
        private Player _player;
        private Holding _holding;
        private NewsItem _newsItem;
        private Prediction _prediction;

        #endregion
        #region Interface

        public void Execute(Offer offer, Player player, Holding holding, Prediction prediction)
        {
            if (offer == null)
                throw new ArgumentNullException("offer");
            if (player == null)
                throw new ArgumentNullException("player");
            

            if (offer.PlayerId != player.Id)
                throw new ArgumentException(String.Format("Offer does not belong to {0}.", player.UserName));
            if (holding != null && holding.PlayerId != player.Id)
                throw new ArgumentException(String.Format("{0} does not own holding.", player.UserName));
            if (holding != null && holding.PredictionId != offer.PredictionId)
                throw new ArgumentException("The holding is not of the prediction of the offer.");
            if (offer.IsAccepted)
                throw new ArgumentException("This offer has already been accepted. It is too late to remove it.");
            if (!offer.IsActive)
                throw new ArgumentException("This offer is already inactive.");
            
            _offer = offer;
            _player = player;
            _holding = holding;
            _prediction = prediction;
            PerformRemoval();
        }

        #endregion
        #region Private methods

        private void PerformRemoval()
        {
            _offer.IsActive = false;
            if (_offer.IsBuy)
            {
                _player.Cash += (_offer.NumPredictions * _offer.Price);
            }
            else
            {
                if (_holding == null)
                {
                    _holding = new Holding();
                    _holding.Id = -1;
                    _holding.NumPredictions = 0;
                    _holding.PlayerId = _player.Id;
                    _holding.PredictionId = _offer.PredictionId;
                }
                _holding.NumPredictions += _offer.NumPredictions;
            }

            CreateNewsItem();
        }

        private void CreateNewsItem()
        {
            _newsItem = new NewsItem();
            _newsItem.NewsDate = DateTime.Now;
            _newsItem.PlayerId = _offer.PlayerId;
            _newsItem.PredictionId = _offer.PredictionId;
            _newsItem.ShouldBeShownInMainNews = false;
            _newsItem.Title = String.Format("{0} offer cancelled.", _prediction.Ticker);
            _newsItem.Message = String.Format("The offer for you to {0} {1} {2} {3} for {4}{5} has now been removed.", 
                (_offer.IsBuy ? "sell" : "buy"), 
                _offer.NumPredictions, 
                _prediction.Ticker, 
                (_offer.NumPredictions == 1) ? "stock" : "stocks",
                _offer.Price,
                (_offer.NumPredictions == 1) ? "" : " each");
        }

        #endregion
        #region Properties

        public NewsItem RemoveOfferNewsItem
        {
            get { return _newsItem; }
        }

        public Offer RemoveOfferOffer
        {
            get { return _offer; }
        }

        public Player RemoveOfferPlayer
        {
            get { return _player; }
        }

        public Holding RemoveOfferHolding
        {
            get { return _holding; }
        }

        #endregion
    }
}
